// Copyright (c) 2008 Matthew Johnson
// Licensed under the MIT License (see license.txt)
package actionml.tracing {
	public class Appender implements IAppender {
		private static var _appenders:Array = [];
		public static function get appenders():Array {
			return _appenders;
		}
		public static function addAppender(a:IAppender) {
			_appenders.push(a);
		}
		public static function addAppenderFromXml(xml:XML) {
			var a:IAppender;
			var c:Class = Class["forName"]("actionml.tracing." + xml.name().localName + "Appender");
			if (c) {
				a = new c(Object(xml).getAttributes());
				for each (var filterXml:XML in xml.elements()) {
					a.addFilter(new TraceFilter(Object(filterXml).getAttributes()));
				}
				_appenders.push(a);
			} else {
				trace(xml.name().localName + " is specified in your XML but is not a valid trace element.")
			}
		}
		
		private var _format:String;
		private var _filters:Array = [];
		public function Appender(o:Object) {
			o ||= {};
			_format = o["format"] || "";
			delete o["format"];
			_filters = [new TraceFilter(o)];
		}
		public function addFilter(f:TraceFilter) {
			_filters.push(f);
		}
		public function append(t:Trace) {
			var matchFound:Boolean = false;
			for each (var f:TraceFilter in _filters) {
				if (f.match(t)) {
					matchFound = true;
				}
			}
			if (matchFound || _filters.length == 0) {
				var s:String = _format;
				s = s.replace("{class}", t.className);
				for each (var p:String in ["method", "category", "context", "message", "date", "year", "month", "day", "time", "hour", "minute", "second", "ms", "timer"]) {
					s = s.replace("{" + p + "}", t[p]);
				}
				for each (p in t.getPropertyNames()) {
					s = s.replace("{" + p + "}", t[p]);
				}
				this.appendString(s);
			}
		}
		protected function appendString(s:String) {
			throw new Error(this["constructor"].toString() + " needs to implement appendString.")
		}
	}
}